import json

from flask import current_app
from flask_restful import Resource, reqparse

from comment.models.index import Category, HomeNewProduct, Product, HomeRecommendProduct, CmsSubject, \
    CmsSubjectProductRelation
from comment.utils.data2dict import datalist2dict, data2dict
from comment.utils.shoppping_redis import redis_client


# 商品分类的资源类
class ShoppingCategory(Resource):
    def get(self):
        try:
            data_cache = redis_client.get('index_category')  # 从redis数据库取出来的数据是一个字节型数据。b'[{},{}]'
        except ConnectionError as e:
            current_app.logger.error(e)
            return {'message': 'redis db connect error.'}, 400
        if data_cache:
            # print(type(data))   #取出来的是一个字节数据
            return json.loads(
                data_cache)  # 存入数据时用json.dumps将数据转换成了json格式的字符串，取出来的时候要用json.loads将json字符串解析为相应的 Python 数据结构，如字典、列表、字符串、整数等

        else:  # 如果redis中没有数据就查询mysql
            data = self.getData(0)
            if data:
                for item in data:
                    item.update({'list': ''})
                    data2 = self.getData(item['id'])  # 查询出每一个一级下面所有的二级内容，结果是一个列表
                    if data2:
                        item['list'] = data2  # 添加到一级的list键下面
                        for item2 in data2:
                            item2.update({'list': ''})
                            data3 = self.getData(item2['id'])  # 查询每一个二级内容下面所有的三级内容
                            item2['list'] = data3
                # 把查询到的数据写入redis
                redis_client.setex('index_category', 3600 * 24, json.dumps(data))  # 切记数据存入redis中时要转为符合redis数据
                # 库的格式。这里使用dumps将格式转为json格式的字符串。
                return data
            else:
                return {'message': 'none'}

    @staticmethod
    def getData(parent_id):
        res = Category.query.with_entities(Category.id, Category.parent_id, Category.name).filter(
            Category.parent_id == parent_id).order_by(Category.sort.asc()).limit(
            10).all()  # 返回的格式为列表套元组，里面的元组其实不是元组，而是AbstractKeyedTuple，即抽象键元组
        # 注意这里一定要使用with_entities来获取字段，否则取出的数据的格式，可能就不适用自定义的函数了。具体的需要自己再看看。
        if res:
            return datalist2dict(res)  # 这个自定义的函数是将列表里面的AbstractKeyedTuple装换成了字典
        else:
            return 'none'


class Shopping_HomeNewProduct(Resource):
    def get(self):
        res = HomeNewProduct.query.join(Product, HomeNewProduct.product_id == Product.id).with_entities(Product.id,
                                                                                                        Product.default_pic,
                                                                                                        Product.price,
                                                                                                        Product.product_name,
                                                                                                        Product.rel_category3_id).limit(
            10).all()
        if res:
            return datalist2dict(res)
        else:
            return {'message': 'none'}


class Shopping_HomeRecommendProduct(Resource):
    def get(self):
        try:
            data = redis_client.get('index_HomeRecommendProduct')
        except ConnectionError as e:
            current_app.logger.error(e)  # error 是日志的级别，为什么是error？因为这里是记录错误的
            return {'message': 'redis db connect error.'}, 400
        if data:
            return json.loads(data)
        else:  # redis中没有数据则查询mysql中的数据
            res = HomeRecommendProduct.query.join(Product, HomeRecommendProduct.product_id == Product.id).with_entities \
                (Product.id, Product.default_pic, Product.price, Product.product_name, Product.rel_category3_id).limit(
                10).all()
            if res:
                # 一定要将查出来的数据的格式进行转换！！！！！！！
                data = datalist2dict(res)
                # 将其存储到redis数据库中
                redis_client.setex('index_HomeRecommendProduct', 3600 * 24, json.dumps(data))
                return data
            else:
                return 'none'


class Shopping_RecommendSubject(Resource):
    def get(self):
        res = CmsSubject.query.filter(
            CmsSubject.show_status == 1).all()

        res_list = []
        for res_obj in res:
            if res_obj:
                data = data2dict(res_obj)
                res_product = CmsSubjectProductRelation.query.join \
                    (Product, CmsSubjectProductRelation.product_id == Product.id).filter \
                    (CmsSubjectProductRelation.subject_id == res_obj.id).with_entities \
                    (Product.id, Product.default_pic, Product.price, Product.product_name,
                     Product.rel_category3_id).limit(10).all()
                if res_product:
                    data_product = datalist2dict(res_product)
                    data['productList'] = data_product
                    res_list.append(data)
        if len(res_list) > 0:
            return res_list
        else:
            return {'message': 'none'}
